import json
from typing import Optional, List, Dict, Any
from datetime import datetime
from sqlalchemy import desc, or_
from .models import OrderAccount
from .sqlalchemy_database import SQLAlchemyDatabaseManager

class OrderAccountManager:
    def __init__(self):
        """
        初始化订单账号管理器
        """
        self.db = SQLAlchemyDatabaseManager()

    def get_account_by_id(self, account_id: int) -> Optional[Dict[str, Any]]:
        """
        根据ID获取账号
        :param account_id: 账号ID
        :return: 账号信息字典或None
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        return self._convert_model_to_dict(account) if account else None

    def get_account_by_uu_user_id(self, uu_user_id: int) -> Optional[Dict[str, Any]]:
        """
        根据悠悠用户ID获取账号
        :param uu_user_id: 悠悠用户ID
        :return: 账号信息字典或None
        """
        session, query = self.db.query_with_session(OrderAccount)
        try:
            account = query.filter(OrderAccount.uu_user_id == uu_user_id).first()
            return self._convert_model_to_dict(account) if account else None
        finally:
            session.close()

    def get_active_accounts(self) -> List[Dict[str, Any]]:
        """
        获取所有可用的账号
        :return: 账号列表
        """
        session, query = self.db.query_with_session(OrderAccount)
        try:
            accounts = query.filter(
                OrderAccount.status == 1,
                OrderAccount.uu_alive == 1
            ).all()
            return [self._convert_model_to_dict(account) for account in accounts]
        finally:
            session.close()

    def get_all_accounts(self, limit: int = None, offset: int = None) -> List[Dict[str, Any]]:
        """
        获取所有账号，支持分页
        :param limit: 每页数量
        :param offset: 偏移量
        :return: 账号列表
        """
        session, query = self.db.query_with_session(OrderAccount)
        try:
            if limit is not None and offset is not None:
                query = query.limit(limit).offset(offset)
                
            accounts = query.all()
            return [self._convert_model_to_dict(account) for account in accounts]
        finally:
            session.close()

    def search_accounts(self, keyword: str, limit: int = None, offset: int = None) -> List[Dict[str, Any]]:
        """
        搜索账号
        :param keyword: 搜索关键词
        :param limit: 每页数量
        :param offset: 偏移量
        :return: 账号列表
        """
        session, query = self.db.query_with_session(OrderAccount)
        try:
            query = query.filter(
                or_(
                    OrderAccount.name.like(f"%{keyword}%"),
                    OrderAccount.steam_account_name.like(f"%{keyword}%")
                )
            )
            
            if limit is not None and offset is not None:
                query = query.limit(limit).offset(offset)
                
            accounts = query.all()
            return [self._convert_model_to_dict(account) for account in accounts]
        finally:
            session.close()

    def get_accounts(self, keyword: str = None, limit: int = None, offset: int = None) -> List[Dict[str, Any]]:
        """
        获取所有账号并格式化为表格显示所需的格式，支持搜索和分页
        :param keyword: 搜索关键词
        :param limit: 每页数量
        :param offset: 偏移量
        :return: 账号列表
        """
        # 获取账号数据
        if keyword:
            accounts = self.search_accounts(keyword, limit, offset)
        else:
            accounts = self.get_all_accounts(limit, offset)
        
        formatted_accounts = []
        for account in accounts:
            # 格式化账号状态
            status = "失效" if account["status"] == 0 else "正常"
            
            formatted_account = {
                "id": account["id"],
                "uu_user_id": account["uu_user_id"] or "",
                "name": account["name"] or "",
                "uu_token": account["uu_token"] or "",
                "device_id": account["device_id"] or "",
                "uk": account["uk"] or "",
                "create_at": account["create_at"] or "",
                "update_at": account["update_at"] or "",
                "status": status
            }
            formatted_accounts.append(formatted_account)
            
        return formatted_accounts

    def add_account(self, account_data: Dict[str, Any]) -> bool:
        """
        添加或更新账号
        
        Args:
            account_data: 账号数据字典
            
        Returns:
            bool: 是否成功
        """
        try:
            session, query = self.db.query_with_session(OrderAccount)
            try:
                # 检查是否已存在相同uu_user_id的账号
                uu_user_id = account_data.get('uu_user_id')
                if not uu_user_id:
                    print("缺少uu_user_id")
                    return False
                    
                existing_account = query.filter(OrderAccount.uu_user_id == uu_user_id).first()
                
                if existing_account:
                    # 更新现有账号
                    for key, value in account_data.items():
                        if hasattr(existing_account, key):
                            setattr(existing_account, key, value)
                    self.db.update_obj(existing_account)
                else:
                    # 创建新账号
                    new_account = OrderAccount(**account_data)
                    self.db.add(new_account)
                
                return True
                
            finally:
                session.close()
                
        except Exception as e:
            print(f"添加或更新账号时发生错误: {str(e)}")
            return False

    def update_account(self, account_id: int, account_data: Dict[str, Any]) -> bool:
        """
        更新账号信息
        :param account_id: 账号ID
        :param account_data: 要更新的数据
        :return: 是否成功
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        if not account:
            return False
            
        account_data = self._prepare_account_data(account_data)
        account_data['update_at'] = int(datetime.now().timestamp() * 1000)
        
        for key, value in account_data.items():
            setattr(account, key, value)
            
        self.db.update_obj(account)
        return True

    def update_account_status(self, account_id: int, status: int) -> bool:
        """
        更新账号状态
        :param account_id: 账号ID
        :param status: 新状态
        :return: 是否成功
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        if not account:
            return False
            
        account.status = status
        account.update_at = int(datetime.now().timestamp() * 1000)
        
        self.db.update_obj(account)
        return True

    def update_uu_alive(self, account_id: int, alive: int, desc: str = "") -> bool:
        """
        更新悠悠账号存活状态
        :param account_id: 账号ID
        :param alive: 存活状态
        :param desc: 失效描述
        :return: 是否成功
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        if not account:
            return False
            
        account.uu_alive = alive
        account.uu_invalid_desc = desc if not alive else ""
        account.update_at = int(datetime.now().timestamp() * 1000)
        
        if alive:
            account.uu_alive_times += 1
            
        self.db.update_obj(account)
        return True

    def update_steam_alive(self, account_id: int, alive: int, desc: str = "") -> bool:
        """
        更新Steam账号存活状态
        :param account_id: 账号ID
        :param alive: 存活状态
        :param desc: 失效描述
        :return: 是否成功
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        if not account:
            return False
            
        account.steam_alive = alive
        account.steam_invalid_desc = desc if not alive else ""
        account.update_at = int(datetime.now().timestamp() * 1000)
        
        self.db.update_obj(account)
        return True

    def update_safe_verify(self, account_id: int, verify_status: int) -> bool:
        """
        更新安全验证状态
        :param account_id: 账号ID
        :param verify_status: 验证状态
        :return: 是否成功
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        if not account:
            return False
            
        account.verify_status = verify_status
        account.verify_at = int(datetime.now().timestamp() * 1000)
        account.update_at = account.verify_at
        
        self.db.update_obj(account)
        return True

    def delete_account(self, account_id: int) -> bool:
        """
        删除账号
        :param account_id: 账号ID
        :return: 是否成功
        """
        account = self.db.get_by_id(OrderAccount, account_id)
        if not account:
            return False
            
        self.db.delete_obj(account)
        return True

    def check_uu_user_id_exists(self, uu_user_id):
        """检查uu_user_id是否已存在
        
        Args:
            uu_user_id: UU用户ID
            
        Returns:
            bool: 如果已存在返回True，否则返回False
        """
        session = self.db.get_session()
        try:
            account = session.query(OrderAccount).filter(
                OrderAccount.uu_user_id == uu_user_id
            ).first()
            return account is not None
        except Exception as e:
            print(f"检查uu_user_id是否存在时发生错误: {str(e)}")
            return False
        finally:
            session.close()

    def _prepare_account_data(self, account_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理账号数据，确保数据格式正确
        """
        prepared_data = {}
        
        # 处理登录返回的数据
        if 'token' in account_data:
            prepared_data['uu_token'] = account_data['token']
            
        # 使用LoginManager处理后的字段名
        field_mappings = {
            'uu_user_id': 'uu_user_id',
            'nickname': 'nickname',
            'avatar': 'avatar',
            'steam_id': 'steam_id',
            'device_id': 'device_id',
            'device_info': 'device_info',
            'uk': 'uk',
            'status': 'status',
            'steam_cookie': 'steam_cookie',
            'balance_limit': 'balance_limit',
            'steam_login_type': 'steam_login_type',
            'steam_account_name': 'steam_account_name',
            'steam_password': 'steam_password',
            'steam_api_key': 'steam_api_key',
            'steam_mafile': 'steam_mafile',
            'pay_type': 'pay_type',
            'pay_methods': 'pay_methods',
            'buy_method': 'buy_method'
        }
        
        for src_key, dst_key in field_mappings.items():
            if src_key in account_data:
                prepared_data[dst_key] = account_data[src_key]
                
        # 如果有nickname，使用nickname作为name
        if 'nickname' in account_data:
            prepared_data['name'] = account_data['nickname']
            
        # 处理标签字段
        if 'tags' in account_data:
            if isinstance(account_data['tags'], list):
                prepared_data['tags'] = json.dumps(account_data['tags'])
            elif not account_data['tags']:
                prepared_data['tags'] = '[]'
                
        # 处理device_info字段
        if 'device_info' in account_data:
            if isinstance(account_data['device_info'], dict):
                prepared_data['device_info'] = json.dumps(account_data['device_info'])
            elif not account_data['device_info']:
                prepared_data['device_info'] = '{}'
                
        # 设置默认值
        if 'status' not in prepared_data:
            prepared_data['status'] = 1
        if 'uu_alive' not in prepared_data:
            prepared_data['uu_alive'] = 1  # 新登录的账号默认在线
            
        return prepared_data

    def _convert_model_to_dict(self, account: OrderAccount) -> Dict[str, Any]:
        """
        将OrderAccount模型转换为字典
        :param account: 账号模型
        :return: 账号字典
        """
        if not account:
            return {}
            
        data = {
            'id': account.id,
            'name': account.name,
            'uu_token': account.uu_token,
            'device_id': account.device_id,
            'steam_cookie': account.steam_cookie,
            'status': account.status,
            'uu_alive': account.uu_alive,
            'steam_alive': account.steam_alive,
            'safe_verify': account.safe_verify,
            'uu_user_id': account.uu_user_id,
            'avatar': account.avatar,
            'nickname': account.nickname,
            'uu_invalid_desc': account.uu_invalid_desc,
            'steam_invalid_desc': account.steam_invalid_desc,
            'steam_id': account.steam_id,
            'uu_steam_id': account.uu_steam_id,
            'balance_limit': account.balance_limit,
            'balance_monitor': account.balance_monitor,
            'buy_fail_monitor': account.buy_fail_monitor,
            'steam_login_type': account.steam_login_type,
            'steam_account_name': account.steam_account_name,
            'steam_password': account.steam_password,
            'steam_api_key': account.steam_api_key,
            'steam_mafile': account.steam_mafile,
            'pay_type': account.pay_type,
            'pay_methods': account.pay_methods,
            'buy_method': account.buy_method,
            'create_at': account.create_at,
            'update_at': account.update_at,
            'uu_alive_times': account.uu_alive_times,
            'uk': account.uk,
            'device_info': account.device_info if isinstance(account.device_info, dict) else {}
        }
        return data
